/*******************************************************************************
 * Copyright (c) 2014 Steffen Mikkelsen
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Steffen Mikkelsen - initial API and implementation
 ******************************************************************************/
package com.subsecret.secureconnection.securestream.layers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.junit.Test;

import com.subsecret.secureconnection.securestream.layers.obfuscation.ObfuscationLayer;
import com.subsecret.secureconnection.securestream.stream.obfuscation.ObfuscationInputStream;
import com.subsecret.secureconnection.securestream.stream.obfuscation.ObfuscationOutputStream;

public class ObfuscationLayerTest {
    @Test
    public void obfuscationLayer() throws IOException, InterruptedException {
        LayerTestTools.testSecureStream(false, new ObfuscationLayer(), new ObfuscationLayer(), new ObfuscationLayer());
    }
    
    @Test
    public void obfuscationEncryptionDecryption() {
        byte[] secret = new byte[] { 1, 3, 5, 3, 4, 5, 1, 2, 3 };
        byte[] byteDecryptionTable = ObfuscationInputStream.byteDecryptionTable(secret);
        byte[] byteEncryptionTable = ObfuscationOutputStream.byteEncryptionTable(secret);
        byte[] msg = new byte[] { -1 };
        byte[] enc = new byte[] { -1, -100, 0, 101, 127 };
        byte[] dec = new byte[msg.length];
        for (int i = 0; i < msg.length; i++) {
            enc[i] = byteEncryptionTable[128 + msg[i]];
            dec[i] = byteDecryptionTable[128 + enc[i]];
        }
        org.junit.Assert.assertArrayEquals(msg, dec);
    }
    
    @Test
    public void obfuscationLayerSimple() throws IOException {
        for (int i = -128; i < 128; i++) {
            byte[] secret = new byte[] { 7, 3, 1, 4, 5, 9, 6, 1, -44 };
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObfuscationOutputStream oos = new ObfuscationOutputStream(baos, secret);
            ObfuscationOutputStream oos2 = new ObfuscationOutputStream(oos, secret);
            ObfuscationOutputStream oos3 = new ObfuscationOutputStream(oos2, secret);
            OutputStream os = oos3;
            
            os.write(new byte[] { (byte) i });
            os.write(i);
            
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObfuscationInputStream ois = new ObfuscationInputStream(bais, secret);
            ObfuscationInputStream ois2 = new ObfuscationInputStream(ois, secret);
            ObfuscationInputStream ois3 = new ObfuscationInputStream(ois2, secret);
            
            InputStream is = ois3;
            byte[] buf = new byte[1];
            is.read(buf);
            byte a = buf[0];
            // System.out.println(a);
            byte b = (byte) is.read();
            // System.out.println(b);
            // System.out.println("Input was " + i);
            org.junit.Assert.assertEquals(a, b);
            org.junit.Assert.assertEquals(i, b);
            os.close();
            is.close();
        }
    }
}
